package org.cfx.auth.interceptor;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.cfx.auth.mapper.AuthRoleMapper;
import org.cfx.basic.annotation.Permission;
import org.cfx.basic.myenum.LoginContext;
import org.cfx.basic.util.RedisUtil;
import org.cfx.org.domain.Employee;
import org.cfx.org.domain.dto.EmployeeDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @author RTX 9090
 */

@Component
public class AuthInterceptor implements HandlerInterceptor {

    /**
     * 登录拦截器
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Autowired
    private AuthRoleMapper authRoleMapper;

    @Resource
    private RedisUtil redisUtil;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /*
            1.先不考虑不登陆也能访问的资源
            2.检查用户是否登录
                2.1 获取toke
                2.2 没有就跳转会 登录页面
                2.3 和全局map比较是否存在，-->没有就视为过期，跳回登录页面。
         */

        System.out.println(request.getRequestURI());

        String token = request.getHeader("TOKEN");
        response.setContentType("application/json;charset=UTF-8");
        if (token == null){
            PrintWriter out = response.getWriter();
            //返回json {"success":true,"message":"请登录","data":"noAuth"}
            out.println("{\"success\":false,\"message\":\"请登录\",\"data\":\"noAuth\"}");
            out.flush();
            out.close();
            //拦截
            return false;
        }

        //和全局map比较是否存在，-->没有就视为过期，跳回登录页面。
//        Employee employee = LoginContext.CONTEXT.getMap().get(token);
        //与redis里的key比较是否存在
        EmployeeDto employee = redisUtil.getKey(token);
        if (employee == null){
            PrintWriter out = response.getWriter();
            //返回json {"success":true,"message":"请登录","data":"noAuth"}
            out.println("{\"success\":false,\"message\":\"请登录\",\"data\":\"noAuth\"}");
            out.flush();
            out.close();
            //拦截
            return false;
        }

        //鉴权 登录的用户是否有权限访问某些资源
        /*
           1.访问的方法是否要鉴权
                如果不需要，直接放行

           2.知道是什么角色，有哪些权限
                角色是否拥有该资源
         */
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //获取目标方法上的注解
        Permission annotation = method.getAnnotation(Permission.class);
        if (annotation!=null){//方法需要做鉴权
            //确定要做权限鉴定
            List<String> list = authRoleMapper.getSnByEmpId(employee.getUser().getId());

            String authRole = handlerMethod.getBeanType().getSimpleName()+":"+method.getName();
            if (!list.contains(authRole)) {
                PrintWriter out = response.getWriter();
                out.println("{\"success\":false,\"message\":\"没有权限\",\"data\":\"Forbidden\"}");
                out.flush();
                out.close();
                return false;
            }

        }
        //放行
        return true;
    }
}
